package model.factory;

import java.util.Random;

import model.geneticAlgorithm.organismBreedingStrategies.CrossoverOrganismBreedingStrategy;
import model.geneticAlgorithm.organismBreedingStrategies.OrganismBreedingStrategy;
import model.organism.DangerousChromosoneCharacterException;
import model.organism.Organism;
import model.organism.SimpleStringOrganism;

public class SimpleStringOrganismFactory {
	
	private static Random rand = new Random(System.currentTimeMillis());
	private static OrganismBreedingStrategy breedingStrategy = new CrossoverOrganismBreedingStrategy();
	
	public static SimpleStringOrganism createOrganismWithChromosones(String chromosones)
	{
		SimpleStringOrganism simpleStringOrganism = new SimpleStringOrganism();
		int i = 0;
		for(char c: chromosones.toCharArray())
		{
			try
			{
				simpleStringOrganism.setChromosoneAtIndex(i, (Character)c);
			} catch (DangerousChromosoneCharacterException e)
			{
				e.printStackTrace();
			}
		}
		return simpleStringOrganism;
	}

	public static SimpleStringOrganism createRandomOrganism()
	{
		SimpleStringOrganism organism = new SimpleStringOrganism();
		for(int i = 0; i < organism.getNumberOfGenes(); i++)
		{
			Character c = new Character((char)((Math.abs(rand.nextInt())%organism.getNumberOfAlleles()) + 37));
			setChromosoneAtIndexInOrganism(i, organism, c);
		}
		return organism;
	}
	
	//sets the chromosone to a random value if it's a dangerous character
	private static void setChromosoneAtIndexInOrganism(int index, SimpleStringOrganism organism, Character c)
	{
		try
		{
			organism.setChromosoneAtIndex(index,c);
		} catch (DangerousChromosoneCharacterException e)
		{
			setChromosoneAtIndexInOrganism(index, organism, new Character((char)((Math.abs(rand.nextInt())%organism.getNumberOfAlleles()) + 37)));
		}
	}
	
	public static SimpleStringOrganism breedOrganism(SimpleStringOrganism parent1, SimpleStringOrganism parent2, float mutationRate) throws Exception
	{
		if(parent1 == null || parent2 == null)
		{
			throw new Exception();
		}
		
		return (SimpleStringOrganism) breedingStrategy.breedOrganism(parent1, parent2, mutationRate);
	}
	
	public static SimpleStringOrganism createOrganism()
	{
		return new SimpleStringOrganism("XXXXXXXXXXXXXXXXXXXXXX");
	}
	
	public static SimpleStringOrganism createOrganism(String chromosones)
	{
		return new SimpleStringOrganism(chromosones);
	}
	
}
